package com.yuncheng.spcyApi.spcyService;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.yuncheng.entity.YcSysUser;
import org.apache.commons.collections.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuncheng.spcyApi.constant.common.BusinessConstant;
import com.yuncheng.spcyApi.constant.common.LogConstant;
import com.yuncheng.spcyApi.constant.common.SpcyConstant;
import com.yuncheng.spcyApi.dto.SpcyGzjlDto;
import com.yuncheng.spcyApi.entity.*;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.spcyApi.mapper.SpcyOaGzjlMapper;
import com.yuncheng.spcyApi.schedule.ActiveScheduleTask;
import com.yuncheng.spcyApi.service.*;
import com.yuncheng.spcyApi.utils.*;
import com.yuncheng.vo.CurrentUserVo;
import com.yuncheng.vo.HttpResult;
import com.yuncheng.spcyApi.vo.spcy.SpcyOaGzjlVo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import utils.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Component(value = "spcyGzglService")
public class SpcyGzglService {

    private static final Logger log = LoggerFactory.getLogger(SpcyGzglService.class);

    @Resource
    private ISpcyLogService spcyLogService;

    @Resource
    private ISpcyOaGzxkService spcyOaGzxkService;

    @Resource
    private ISpcyOaGztclxService spcyOaGztclxService;

    @Resource
    private ISpcyOaGztcService spcyOaGztcService;

    @Resource
    private ISpcyOaGzjlService spcyOaGzjlService;

    @Resource
    private SpcyOaGzjlMapper spcyOaGzjlMapper;

    @Resource
    private ISpcyOaGzxqService spcyOaGzxqService;

    @Resource
    private IYcSysUserService ycSysUserService;

    @Resource
    private LocalFileUploadUtils localFileUploadUtils;

    @Resource
    private BusinessConstant businessConstant;

    @Resource
    private ActiveScheduleTask activeScheduleTask;

    // 工资项库 - 有效状态
    public final String GZXK_YXZT_YX = "0"; // 有效
    public final String GZXK_YXZT_WX = "1"; // 无效

    // 工资记录-确认状态
    public final String GZJL_QRZT_WQR = "0"; // 未确认
    public final String GZJL_QRZT_YQR = "1"; // 已确认

    // 工作项-实发工资
    public final String GZXK_GDLX_SFGZ = "实发工资";

    // 工资项库-固定类型
    public final String GZXK_GDLX_XH = "序号";
    public final String GZXK_GDLX_XM = "姓名";
    public final String GZXK_GDLX_NF = "年份";
    public final String GZXK_GDLX_YF = "月份";

    /**
     * 分页查询 - 工资项库
     * @param gzxk
     * @param pageNo
     * @param pageSize
     * @return
     */
    public HttpResult queryPageGzxkList(SpcyOaGzxk gzxk,Integer pageNo, Integer pageSize){
        Page<SpcyOaGzxk> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<SpcyOaGzxk> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(StringUtils.isNotBlank(gzxk.getFmc()),SpcyOaGzxk::getFmc,gzxk.getFmc());

        if (StringUtils.isNotBlank(gzxk.getFyxzt())){
            queryWrapper.eq(SpcyOaGzxk::getFyxzt, gzxk.getFyxzt());
        }else {
            queryWrapper.eq(SpcyOaGzxk::getFyxzt, GZXK_YXZT_YX);
        }

        queryWrapper.orderByAsc(SpcyOaGzxk::getForder);
        queryWrapper.orderByAsc(SpcyOaGzxk::getCreateTime);
        IPage<SpcyOaGzxk> pageList = spcyOaGzxkService.page(page, queryWrapper);
        return HttpResult.ok(pageList);
    }

    /**
     * 分页查询 - 工资套餐类型
     * @param gztclx
     * @param pageNo
     * @param pageSize
     * @return
     */
    public HttpResult queryPageGztclxList(SpcyOaGztclx gztclx,Integer pageNo, Integer pageSize){
        Page<SpcyOaGztclx> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<SpcyOaGztclx> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(StringUtils.isNotBlank(gztclx.getFtcmc()),SpcyOaGztclx::getFtcmc,gztclx.getFtcmc());
        queryWrapper.like(StringUtils.isNotBlank(gztclx.getFyear()),SpcyOaGztclx::getFyear,gztclx.getFyear());
        queryWrapper.like(StringUtils.isNotBlank(gztclx.getFbz()),SpcyOaGztclx::getFbz,gztclx.getFbz());

        queryWrapper.orderByAsc(SpcyOaGztclx::getCreateTime);
        IPage<SpcyOaGztclx> pageList = spcyOaGztclxService.page(page, queryWrapper);
        return HttpResult.ok(pageList);
    }

    /**
     * 分页查询 - 工资记录
     * @param gzjl
     * @param onlyCurrentUser 是否查询我的 (true/false)
     * @return
     */
    public HttpResult queryPageGzjlList(SpcyOaGzjl gzjl,Integer pageNo, Integer pageSize,boolean onlyCurrentUser){

        Page<SpcyOaGzjl> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<SpcyOaGzjl> queryWrapper = new LambdaQueryWrapper<>();

        if (onlyCurrentUser){
            CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
            if (currentUser != null){
                queryWrapper.eq(SpcyOaGzjl::getFuserid, currentUser.getId());
                queryWrapper.eq(SpcyOaGzjl::getFqrzt, GZJL_QRZT_YQR);
            }
        }

        queryWrapper.like(StringUtils.isNotBlank(gzjl.getFnf()), SpcyOaGzjl::getFnf,gzjl.getFnf());
        queryWrapper.like(StringUtils.isNotBlank(gzjl.getFxm()), SpcyOaGzjl::getFxm, gzjl.getFxm());
        queryWrapper.like(StringUtils.isNotBlank(gzjl.getFyf()), SpcyOaGzjl::getFyf, gzjl.getFyf());
        queryWrapper.like(StringUtils.isNotBlank(gzjl.getFqrzt()), SpcyOaGzjl::getFqrzt, gzjl.getFqrzt());
        queryWrapper.like(StringUtils.isNotBlank(gzjl.getFgztclx()), SpcyOaGzjl::getFgztclx, gzjl.getFgztclx());

        queryWrapper.orderByAsc(SpcyOaGzjl::getForder);
        queryWrapper.orderByAsc(SpcyOaGzjl::getCreateTime);
        IPage<SpcyOaGzjl> pageList = spcyOaGzjlService.page(page, queryWrapper);

        return HttpResult.ok(pageList);
    }

    /**
     * 获取数组 - 工资项库
     * @param fmc 工资项名称
     * @return
     */
    public HttpResult getAllGzxkList(String fmc){
        LambdaQueryWrapper<SpcyOaGzxk> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(StringUtils.isNotBlank(fmc),SpcyOaGzxk::getFmc,fmc);
        queryWrapper.eq(SpcyOaGzxk::getFyxzt,GZXK_YXZT_YX);

        queryWrapper.orderByAsc(SpcyOaGzxk::getForder);
        queryWrapper.orderByAsc(SpcyOaGzxk::getCreateTime);
        List<SpcyOaGzxk> list = spcyOaGzxkService.list(queryWrapper);

        return HttpResult.ok(list);
    }

    /**
     * 获取所有工资套餐类型数据
     */
    public HttpResult getAllGztclxList(){
        List<String> gztcList = new ArrayList<>();

        List<SpcyOaGztclx> gztclxList = spcyOaGztclxService.list(new LambdaQueryWrapper<SpcyOaGztclx>()
                .orderByAsc(SpcyOaGztclx::getCreateTime));

        if (CollectionUtils.isNotEmpty(gztclxList)){
            gztcList = gztclxList.stream().map(SpcyOaGztclx::getFtcmc).collect(Collectors.toList());
        }

        return HttpResult.ok(gztcList);
    }

    /**
     * 获取所有工资的姓名数据
     * @return
     */
    public HttpResult getAllGzjlUserList(){
        List<String> list = spcyOaGzjlMapper.getAllGzjlUserList();

        return HttpResult.ok(list);
    }




    /**
     * 新增 - 工资项库
     * @param gzxk
     * @return
     */
    public HttpResult addGzxk(SpcyOaGzxk gzxk){
        if (StringUtils.isBlank(gzxk.getFmc())){
            throw new BusinessException("工资项名称为空！");
        }

        List<SpcyOaGzxk> sizeList = spcyOaGzxkService.list();
        int count = sizeList.size() + 1;
        gzxk.setId(GetUuIdUtils.ReplaceUuId());
        gzxk.setForder(count);
        gzxk.setFyxzt(GZXK_YXZT_YX);
        spcyOaGzxkService.save(gzxk);

        String log = "添加-工资管理-工资项库：";
        log += LogUtils.MapToStringMethod(ObjectToMapUtils.objectToMap(gzxk));
        spcyLogService.addLogs(LogConstant.LOGS_GZGL,log,gzxk.getId(), SpcyConstant.LOGS_SYS_TYPE_XZ,SpcyConstant.LOGS_SYS_TYPE_XZ);

        HttpResult httpResult = new HttpResult(true);
        httpResult.setResult(gzxk);
        httpResult.setMessage("保存成功");
        return httpResult;
    }

    /**
     * 新增 - 工资套餐类型
     * @param gztclx
     * @return
     */
    public HttpResult addGztclx(SpcyOaGztclx gztclx){
        if (StringUtils.isBlank(gztclx.getFtcmc())){
            throw new BusinessException("工资套餐名称为空！");
        }

        gztclx.setId(GetUuIdUtils.ReplaceUuId());
        gztclx.setFyear(DateConversionUtils.DateToYear(new Date()));
        spcyOaGztclxService.save(gztclx);

        String log = "添加-工资管理-工资套餐类型：";
        log += LogUtils.MapToStringMethod(ObjectToMapUtils.objectToMap(gztclx));
        spcyLogService.addLogs(LogConstant.LOGS_GZGL,log,gztclx.getId(), SpcyConstant.LOGS_SYS_TYPE_XZ,SpcyConstant.LOGS_SYS_TYPE_XZ);

        HttpResult httpResult = new HttpResult(true);
        httpResult.setResult(gztclx);
        httpResult.setMessage("保存成功");
        return httpResult;
    }

    /**
     * 新增 - 工资套餐
     * @param paramMap (gztclxid: 工资套餐类型id; gzxkids: 工资项库id(可多个id，逗号拼接))
     * @return
     */
    public HttpResult addGztc(Map<String,String> paramMap){
        String gztclxid = paramMap.get("gztclxid");
        String gzxkids = paramMap.get("gzxkids");

        if (StringUtils.isBlank(gztclxid)){
            throw new BusinessException("请选择工资套餐类型！");
        }

        if (StringUtils.isBlank(gzxkids)){
            throw new BusinessException("请选择工资项！");
        }

        List<String> gzxkIdsList = StringPatternUtils.getListByIds(gzxkids);

        // 工资项库
        List<SpcyOaGzxk> gzxkList = spcyOaGzxkService.listByIds(gzxkIdsList);
        if (CollectionUtils.isEmpty(gzxkList)){
            throw new BusinessException("当前工资项数据不存在，请刷新重试！");
        }

        // 工资套餐类型
        SpcyOaGztclx gztclx = spcyOaGztclxService.getById(gztclxid);
        if (gztclx == null){
            throw new BusinessException("当前工资套餐类型数据不存在，请刷新重试！");
        }

        // 套餐数量
        List<SpcyOaGztc> tcList = spcyOaGztcService.list(new LambdaQueryWrapper<SpcyOaGztc>()
                .eq(SpcyOaGztc::getFtclxid, gztclxid));
        int count = tcList.size();

        // 遍历生成套餐
        for (SpcyOaGzxk gzxk : gzxkList) {
            count += 1;
            SpcyOaGztc gztc = new SpcyOaGztc();
            gztc.setId(GetUuIdUtils.ReplaceUuId());
            gztc.setForder(count);
            gztc.setFtclxid(gztclxid);
            gztc.setFgzxmc(gzxk.getFmc());
            spcyOaGztcService.save(gztc);

            String log = "添加-工资套餐：套餐类型["+gztclx.getFtcmc()+"];";
            log += LogUtils.MapToStringMethod(ObjectToMapUtils.objectToMap(gztc));
            spcyLogService.addLogs(LogConstant.LOGS_GZGL,log,gztclxid, SpcyConstant.LOGS_SYS_TYPE_XZ,SpcyConstant.LOGS_SYS_TYPE_XZ);
        }

        return HttpResult.ok("添加成功");
    }

    /**
     * 更新 - 工资项库
     * @param buffer
     * @return
     */
    public HttpResult updateGzxk(HashMap<String, String> buffer) throws InvocationTargetException, IllegalAccessException {
        if (StringUtils.isEmpty(buffer.get("id"))){
            return HttpResult.error("参数为空！");
        }
        String baseId = buffer.get("id");
        SpcyOaGzxk Update = spcyOaGzxkService.getById(baseId);
        if (Update == null){
            return HttpResult.error("当前基本信息数据不存在，请刷新重试！");
        }

        Map<String, Object> oldMap = ObjectToMapUtils.objectToMap(Update);
        ConvertUtils.register(new DateConvert(), java.util.Date.class);
        // 自动完成页面到bean的数据对接
        BeanUtils.populate(Update, buffer);
        spcyOaGzxkService.updateById(Update);

        String operContent = "工资项库-修改：";
        operContent += LogUtils.BeanModifyMsg(Update,oldMap);

        spcyLogService.addLogs(LogConstant.LOGS_GZGL,operContent,baseId,SpcyConstant.LOGS_SYS_TYPE_XG,SpcyConstant.LOGS_SYS_TYPE_XG);

        HttpResult httpResult = new HttpResult(true);
        httpResult.setResult(Update);
        httpResult.setMessage("保存成功");
        return httpResult;
    }

    /**
     * 更新 - 工资套餐类型
     * @param buffer
     * @return
     */
    public HttpResult updateGztclx(HashMap<String, String> buffer) throws InvocationTargetException, IllegalAccessException {
        if (StringUtils.isEmpty(buffer.get("id"))){
            return HttpResult.error("参数为空！");
        }
        String baseId = buffer.get("id");
        SpcyOaGztclx Update = spcyOaGztclxService.getById(baseId);
        if (Update == null){
            return HttpResult.error("当前基本信息数据不存在，请刷新重试！");
        }

        Map<String, Object> oldMap = ObjectToMapUtils.objectToMap(Update);
        ConvertUtils.register(new DateConvert(), java.util.Date.class);
        // 自动完成页面到bean的数据对接
        BeanUtils.populate(Update, buffer);
        spcyOaGztclxService.updateById(Update);

        String operContent = "工资套餐类型-修改：";
        operContent += LogUtils.BeanModifyMsg(Update,oldMap);

        spcyLogService.addLogs(LogConstant.LOGS_GZGL,operContent,baseId,SpcyConstant.LOGS_SYS_TYPE_XG,SpcyConstant.LOGS_SYS_TYPE_XG);

        HttpResult httpResult = new HttpResult(true);
        httpResult.setResult(Update);
        httpResult.setMessage("保存成功");
        return httpResult;
    }

    /**
     * 更新 - 工资套餐
     * @param buffer
     * @return
     */
    public HttpResult updateGztc(HashMap<String, String> buffer) throws InvocationTargetException, IllegalAccessException {
        if (StringUtils.isEmpty(buffer.get("id"))){
            return HttpResult.error("参数为空！");
        }
        String baseId = buffer.get("id");
        SpcyOaGztc Update = spcyOaGztcService.getById(baseId);
        if (Update == null){
            return HttpResult.error("当前基本信息数据不存在，请刷新重试！");
        }

        Map<String, Object> oldMap = ObjectToMapUtils.objectToMap(Update);
        ConvertUtils.register(new DateConvert(), java.util.Date.class);
        // 自动完成页面到bean的数据对接
        BeanUtils.populate(Update, buffer);
        spcyOaGztcService.updateById(Update);

        String operContent = "工资套餐-修改：";
        operContent += LogUtils.BeanModifyMsg(Update,oldMap);

        spcyLogService.addLogs(LogConstant.LOGS_GZGL,operContent,baseId,SpcyConstant.LOGS_SYS_TYPE_XG,SpcyConstant.LOGS_SYS_TYPE_XG);

        HttpResult httpResult = new HttpResult(true);
        httpResult.setResult(Update);
        httpResult.setMessage("保存成功");
        return httpResult;
    }

    /**
     * 删除工资项库 - 通过工资项库id
     */
    public HttpResult deleteGzxk(String id){
        if (StringUtils.isEmpty(id)){
            return HttpResult.error("参数为空！");
        }

        SpcyOaGzxk bean = spcyOaGzxkService.getById(id);
        if (bean == null){
            return HttpResult.error("当前数据不存在，请刷新重试！");
        }
        spcyOaGzxkService.removeById(id);

        String operContent = "删除-工资项库：";
        operContent += LogUtils.MapToStringMethod(ObjectToMapUtils.objectToMap(bean));
        spcyLogService.addLogs(LogConstant.LOGS_GZGL,operContent,id,SpcyConstant.LOGS_SYS_TYPE_SC,SpcyConstant.LOGS_SYS_TYPE_SC);

        return HttpResult.ok("删除成功");
    }

    /**
     * 删除工资套餐类型 - 通过工资套餐类型id
     */
    public HttpResult deleteGztclx(String id){
        if (StringUtils.isEmpty(id)){
            return HttpResult.error("参数为空！");
        }
        SpcyOaGztclx bean = spcyOaGztclxService.getById(id);
        if (bean == null){
            return HttpResult.error("当前数据不存在，请刷新重试！");
        }
        spcyOaGztclxService.removeById(id);

        String operContent = "删除-工资套餐类型：";
        operContent += LogUtils.MapToStringMethod(ObjectToMapUtils.objectToMap(bean));
        spcyLogService.addLogs(LogConstant.LOGS_GZGL,operContent,id,SpcyConstant.LOGS_SYS_TYPE_SC,SpcyConstant.LOGS_SYS_TYPE_SC);

        return HttpResult.ok("删除成功");
    }

    /**
     * 删除工资套餐 - 通过工资套餐id
     */
    public HttpResult deleteGztc(String id){
        if (StringUtils.isEmpty(id)){
            return HttpResult.error("参数为空！");
        }
        SpcyOaGztc bean = spcyOaGztcService.getById(id);
        if (bean == null){
            return HttpResult.error("当前数据不存在，请刷新重试！");
        }
        spcyOaGztcService.removeById(id);

        String operContent = "删除-工资套餐：";
        operContent += LogUtils.MapToStringMethod(ObjectToMapUtils.objectToMap(bean));
        spcyLogService.addLogs(LogConstant.LOGS_GZGL,operContent,id,SpcyConstant.LOGS_SYS_TYPE_SC,SpcyConstant.LOGS_SYS_TYPE_SC);

        return HttpResult.ok("删除成功");
    }

    /**
     * 删除工资记录-通过工资记录id
     */
    public HttpResult deleteGzjl(String id){
        if (StringUtils.isEmpty(id)){
            return HttpResult.error("参数为空！");
        }
        SpcyOaGzjl bean = spcyOaGzjlService.getById(id);
        if (bean == null){
            return HttpResult.error("当前数据不存在，请刷新重试！");
        }
        spcyOaGzjlService.removeById(id);

        String operContent = "删除-工资记录：";
        operContent += LogUtils.MapToStringMethod(ObjectToMapUtils.objectToMap(bean));
        spcyLogService.addLogs(LogConstant.LOGS_GZGL,operContent,id,SpcyConstant.LOGS_SYS_TYPE_SC,SpcyConstant.LOGS_SYS_TYPE_SC);

        spcyOaGzxqService.remove(new LambdaQueryWrapper<SpcyOaGzxq>().eq(SpcyOaGzxq::getFgzjlid, id));

        return HttpResult.ok("删除成功");
    }

    /**
     * 查询工资项库 - 通过工资项库id查询
     * @return
     */
    public HttpResult<?> queryGzxkById(String id) {
        if (StringUtils.isEmpty(id)){
            return HttpResult.error("参数为空！");
        }

        SpcyOaGzxk jbxx = spcyOaGzxkService.getById(id);
        return HttpResult.ok(jbxx);
    }

    /**
     * 查询工资套餐类型详情 - 通过工资套餐类型id查询
     * @return
     * // gztclx 工资套餐类型
     * // gztcList 工资套餐
     */
    public HttpResult<?> queryGztclxById(String id) {
        if (StringUtils.isEmpty(id)){
            return HttpResult.error("参数为空！");
        }

        Map resultMap = new HashMap();

        // 工资套餐类型
        SpcyOaGztclx gztclx = spcyOaGztclxService.getById(id);
        resultMap.put("gztclx", gztclx);

        // 工资套餐
        List<SpcyOaGztc> gztcList = spcyOaGztcService.list(new LambdaQueryWrapper<SpcyOaGztc>()
                .eq(SpcyOaGztc::getFtclxid, id)
                .orderByAsc(SpcyOaGztc::getForder)
                .orderByAsc(SpcyOaGztc::getCreateTime));
        resultMap.put("gztcList", gztcList);

        return HttpResult.ok(resultMap);
    }

    /**
     * 发送工资记录-确认状态-已确认
     */
    public void sendGzjlQrzt(String ids){
        if (StringUtils.isBlank(ids)){
            return;
        }
        List<String> listByIds = StringPatternUtils.getListByIds(ids);
        if (CollectionUtils.isEmpty(listByIds)){
            return;
        }

        for (String id : listByIds){
            LambdaUpdateWrapper<SpcyOaGzjl> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(SpcyOaGzjl::getId, id);

            SpcyOaGzjl updateGzjl = new SpcyOaGzjl();
            updateGzjl.setFqrzt(GZJL_QRZT_YQR);
            spcyOaGzjlService.update(updateGzjl,updateWrapper);

        }

        /*SpcyOaGzjl gzjl = spcyOaGzjlService.getById(id);
        if (gzjl == null){
            throw new BusinessException("当前工资记录数据不存在，请刷新重试！");
        }
        gzjl.setFqrzt(GZJL_QRZT_YQR);
        spcyOaGzjlService.updateById(gzjl);*/
    }

    /**
     * 导出工资套餐类型对应模板 - 通过工资套餐类型id
     * @param id
     */
    public void exportGztclxMb(String id, HttpServletResponse response){
        if (StringUtils.isEmpty(id)){
            throw new BusinessException("参数为空！");
        }

        // 工资套餐类型
        SpcyOaGztclx gztclx = spcyOaGztclxService.getById(id);
        if (gztclx == null){
            throw new BusinessException("当前工资套餐类型数据为空！");
        }

        // 工资套餐
        List<SpcyOaGztc> gztcList = spcyOaGztcService.list(new LambdaQueryWrapper<SpcyOaGztc>()
                .eq(SpcyOaGztc::getFtclxid, id)
                .orderByAsc(SpcyOaGztc::getForder)
                .orderByAsc(SpcyOaGztc::getCreateTime));

        List<String> dataList = new ArrayList<>();
        dataList.add(GZXK_GDLX_XH);
        dataList.add(GZXK_GDLX_XM);
        dataList.add(GZXK_GDLX_YF);

        if (CollectionUtils.isNotEmpty(gztcList)){
            for (SpcyOaGztc gztc : gztcList){
                dataList.add(gztc.getFgzxmc());
            }
        }

        // 文件名称
        String title = gztclx.getFtcmc();
        List<List<String>> titleList = new ArrayList<>();
        titleList.add(dataList);
        ExcelUtils.getLocalTitleExcel(titleList,title,response);

    }

    /**
     * 导入工资套餐类型模板数据
     */
    public void importGztclxFile(MultipartFile file,String fileName,String type){

        File fileUpload = localFileUploadUtils.uploadDempFile(file,GetUuIdUtils.ReplaceUuId()+fileName);
        ExcelReader excelReader = ExcelUtil.getReader(fileUpload,0);
        List<Map<String,Object>> excelMapList = excelReader.readAll();

        int count = 1;
        for(Map<String,Object> excelMap : excelMapList){

            Set<Map.Entry<String, Object>> entries = excelMap.entrySet();

            int titleCount = 1;
            // 第一行为标题，不做处理
            if (count > 0) {

                // 工资记录
                SpcyOaGzjl gzjl = new SpcyOaGzjl();
                String gzjlid = GetUuIdUtils.ReplaceUuId();
                gzjl.setId(gzjlid);
                gzjl.setForder(count);
                gzjl.setFnf(DateConversionUtils.DateToYear(new Date()));
                gzjl.setFqrzt(GZJL_QRZT_WQR);
                gzjl.setFgztclx(type);

                // 工资详情
                List<SpcyOaGzxq> gzxqList = new ArrayList<>();

                // 前三列值为固定值
                for (Map.Entry<String, Object> entry : entries) {

                    String key = entry.getKey();
                    String value = "";

                    if (titleCount == 2 && entry.getValue() == null){
                        throw new BusinessException("第"+count+"行数据有误，导入模板第二列必须为[姓名]列，并且不能为空！");
                    }

                    if (titleCount == 3 && entry.getValue() == null){
                        throw new BusinessException("第"+count+"行数据有误，导入模板第三列必须为[月份]列，并且不能为空！");
                    }

                    if (entry.getValue() != null) {
                        value = StringPatternUtils.trimString(entry.getValue().toString());
                    }

                    if (titleCount == 2) {
                        String userid = "";
                        // 根据姓名查找用户id,只存在一个，不存在同名的情况下
                        if (StringUtils.isNotBlank(value)) {
                            List<YcSysUser> userList = ycSysUserService.list(new LambdaQueryWrapper<YcSysUser>()
                                    .eq(YcSysUser::getRealname, value));
                            if (CollectionUtils.isNotEmpty(userList) && userList.size() == 1){
                                userid = userList.get(0).getId();
                            }
                        }
                        gzjl.setFuserid(userid);
                        gzjl.setFxm(value);
                    }

                    if (titleCount == 3){
                        if (value.contains("月")) {
                            gzjl.setFyf(value);
                        }else {
                            gzjl.setFyf(value+"月");
                        }
                    }

                    SpcyOaGzxq gzxq = new SpcyOaGzxq();
                    gzxq.setId(GetUuIdUtils.ReplaceUuId());
                    gzxq.setFgzjlid(gzjlid);
                    gzxq.setFgzxxh(titleCount);
                    gzxq.setFgzxmc(key);
                    gzxq.setFgzxz(value);

                    gzxqList.add(gzxq);

                    // 实发工资生成党费
                    if (StringUtils.isNotBlank(key) && key.equals(GZXK_GDLX_SFGZ)){
                        activeScheduleTask.initPartyDfjl(key, value, gzjl);
                    }

                    // 大于前三固定字段
                    if (titleCount>3) {
                        if (StringUtils.isNotBlank(key)) {
                            // 异步验证是否存在
                            activeScheduleTask.verifyAddGzxk(key);
                        }
                    }

                    titleCount++;
                }

                spcyOaGzjlService.save(gzjl);
                spcyOaGzxqService.saveBatch(gzxqList);
            }

            count++;
        }
        excelReader.close();

        fileUpload.delete();
    }

    /**
     * 导出工资记录数据详情-Excel文件-压缩包
     * @param gzjlVo
     */
    public void exportGztclxDataFile(SpcyOaGzjlVo gzjlVo, HttpServletResponse response){

        // 工资记录
        List<SpcyOaGzjl> gzjlList = new ArrayList<>();

        // 工资记录ids
        String ids = gzjlVo.getIds();

        if (StringUtils.isNotBlank(ids)){
            List<String> gzjlIdList = StringPatternUtils.getListByIds(ids);
            gzjlList = spcyOaGzjlService.listByIds(gzjlIdList);

        }else {
            LambdaQueryWrapper<SpcyOaGzjl> queryWrapper = new LambdaQueryWrapper<>();

            queryWrapper.eq(StringUtils.isNotBlank(gzjlVo.getFnf()), SpcyOaGzjl::getFnf, gzjlVo.getFnf());
            queryWrapper.eq(StringUtils.isNotBlank(gzjlVo.getFxm()), SpcyOaGzjl::getFxm, gzjlVo.getFxm());
            queryWrapper.eq(StringUtils.isNotBlank(gzjlVo.getFyf()), SpcyOaGzjl::getFyf, gzjlVo.getFyf());
            queryWrapper.eq(StringUtils.isNotBlank(gzjlVo.getFqrzt()), SpcyOaGzjl::getFqrzt, gzjlVo.getFqrzt());
            queryWrapper.eq(StringUtils.isNotBlank(gzjlVo.getFgztclx()), SpcyOaGzjl::getFgztclx, gzjlVo.getFgztclx());

            queryWrapper.orderByAsc(SpcyOaGzjl::getForder);
            queryWrapper.orderByAsc(SpcyOaGzjl::getCreateTime);
            gzjlList = spcyOaGzjlService.list(queryWrapper);
        }

        // 工资记录id
        /*List<String> gzjlIdList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(gzjlList)){
            gzjlIdList = gzjlList.stream().map(SpcyOaGzjl::getId).collect(Collectors.toList());
        }*/

        List<File> files = new ArrayList<>();
        List<String> fileNames = new ArrayList<>();

        for (SpcyOaGzjl gzjl : gzjlList) {

            List<String> dataList = new ArrayList<>();
            List<String> titleList = new ArrayList<>();

            // 工资记录详情
            List<SpcyOaGzxq> gzxqList = spcyOaGzxqService.list(new LambdaQueryWrapper<SpcyOaGzxq>()
                    .eq(SpcyOaGzxq::getFgzjlid, gzjl.getId())
                    .orderByAsc(SpcyOaGzxq::getFgzxxh)
                    .orderByAsc(SpcyOaGzxq::getCreateTime));

            if (CollectionUtils.isNotEmpty(gzxqList)) {
                for (SpcyOaGzxq gzxq : gzxqList) {
                    titleList.add(gzxq.getFgzxmc());
                    dataList.add(gzxq.getFgzxz());
                }

                // 文件名称
                String title = gzjl.getFxm()+"-"+gzjl.getFnf()+"-"+gzjl.getFyf();
                List<List<String>> resultList = new ArrayList<>();
                resultList.add(titleList);
                resultList.add(dataList);
                String rootUrl = localFileUploadUtils.getTempFileRootUrl();
                File outFile = ExcelUtils.getLocalDempXlsExcel(resultList, title, rootUrl);

                files.add(outFile);
                fileNames.add(title+".xls");

                List<List<String>> dataLists = new ArrayList<>();
                dataLists.add(dataList);
                rootUrl += "/"+title+".png";
                try {
                    TablePngFileUtils.zdyTablePng(titleList,dataLists,rootUrl);
                } catch (IOException e) {
                    log.error("导出png文件工资记录数据详情出错：{}",e.getMessage());
                }

                files.add(new File(rootUrl));
                fileNames.add(title+".png");
            }
        }

        PdfUtils.downZip(files,fileNames,response);
    }

    /**
     * 通过工资套餐id查询 - 工资套餐
     * @return
     */
    public HttpResult<?> queryGztcById(String id) {
        if (StringUtils.isEmpty(id)){
            return HttpResult.error("参数为空！");
        }

        SpcyOaGztc jbxx = spcyOaGztcService.getById(id);
        return HttpResult.ok(jbxx);
    }

    /**
     * 通过工资记录id查询 - 工资记录详情
     */
    public HttpResult queryGzjlxqById(String id){
        if (StringUtils.isEmpty(id)){
            return HttpResult.error("参数为空！");
        }
        SpcyOaGzjl gzjl = spcyOaGzjlService.getById(id);
        if (gzjl == null){
            return HttpResult.error("当前工资记录为空！");
        }

        // 工资记录详情
        List<SpcyOaGzxq> gzxqList = spcyOaGzxqService.list(new LambdaQueryWrapper<SpcyOaGzxq>()
                .eq(SpcyOaGzxq::getFgzjlid, id)
                .orderByAsc(SpcyOaGzxq::getFgzxxh)
                .orderByAsc(SpcyOaGzxq::getCreateTime));

        List<List<Object>> resultList = new ArrayList<>();

        // 序号
        /*List<Object> xhList = new ArrayList<>();
        xhList.add(GZXK_GDLX_XH);
        xhList.add(gzjl.getForder());
        resultList.add(xhList);*/

        // 姓名
        /*List<Object> xmList = new ArrayList<>();
        xmList.add(GZXK_GDLX_XM);
        xmList.add(gzjl.getFxm());
        resultList.add(xmList);*/

        // 年份
        List<Object> nfList = new ArrayList<>();
        nfList.add(GZXK_GDLX_NF);
        nfList.add(gzjl.getFnf());
        resultList.add(nfList);

        // 月份
        /*List<Object> yfList = new ArrayList<>();
        yfList.add(GZXK_GDLX_YF);
        yfList.add(gzjl.getFyf());
        resultList.add(yfList);*/

        // 其他套餐
        if (CollectionUtils.isNotEmpty(gzxqList)) {
            for (SpcyOaGzxq gzxq : gzxqList) {
                List<Object> qtList = new ArrayList<>();
                qtList.add(gzxq.getFgzxmc());
                qtList.add(gzxq.getFgzxz());
                resultList.add(qtList);
            }
        }

        Map resultMap = new HashMap();
        resultMap.put("gzjlxqList",resultList);
        return HttpResult.ok(resultMap);
    }

    /**
     * 下载Png图片文件-工资记录详情
     * @param id 工资记录id
     */
    public void downGzjlxqPngFile(String id, HttpServletResponse response){
        if (StringUtils.isBlank(id)){
            throw new BusinessException("参数为空！");
        }

        SpcyOaGzjl gzjl = spcyOaGzjlService.getById(id);
        if (gzjl == null){
            throw new BusinessException("当前工资记录数据不存在，请刷新重试！");
        }

        List<String> titleList = new ArrayList<>();
        List<String> dataList = new ArrayList<>();

        // 工资记录详情
        List<SpcyOaGzxq> gzxqList = spcyOaGzxqService.list(new LambdaQueryWrapper<SpcyOaGzxq>()
                .eq(SpcyOaGzxq::getFgzjlid, id)
                .orderByAsc(SpcyOaGzxq::getFgzxxh)
                .orderByAsc(SpcyOaGzxq::getCreateTime));

        if (CollectionUtils.isNotEmpty(gzxqList)) {
            for (SpcyOaGzxq gzxq : gzxqList) {
                titleList.add(gzxq.getFgzxmc());
                dataList.add(gzxq.getFgzxz());
            }

            // 文件名称
            String title = gzjl.getFxm()+"-"+gzjl.getFnf()+"-"+gzjl.getFyf();

            String rootUrl = localFileUploadUtils.getTempFileRootUrl();

            List<List<String>> dataLists = new ArrayList<>();
            dataLists.add(dataList);
            rootUrl += "/"+title+".png";
            try {
                TablePngFileUtils.zdyTablePng(titleList,dataLists,rootUrl);
            } catch (IOException e) {
                log.error("下载Png图片文件-工资记录详情出错：{}",e.getMessage());
            }

            localFileUploadUtils.ejzLocalFileByZdyFile(new File(rootUrl),response);
        }
    }

    /**
     * 下载excel文件-工资记录详情
     * @param id 工资记录id
     */
    public void downGzjlxqExcelFile(String id, HttpServletResponse response){
        if (StringUtils.isBlank(id)){
            throw new BusinessException("参数为空！");
        }

        SpcyOaGzjl gzjl = spcyOaGzjlService.getById(id);
        if (gzjl == null){
            throw new BusinessException("当前工资记录数据不存在，请刷新重试！");
        }

        List<String> titleList = new ArrayList<>();
        List<String> dataList = new ArrayList<>();

        // 工资记录详情
        List<SpcyOaGzxq> gzxqList = spcyOaGzxqService.list(new LambdaQueryWrapper<SpcyOaGzxq>()
                .eq(SpcyOaGzxq::getFgzjlid, id)
                .orderByAsc(SpcyOaGzxq::getFgzxxh)
                .orderByAsc(SpcyOaGzxq::getCreateTime));

        if (CollectionUtils.isNotEmpty(gzxqList)) {
            for (SpcyOaGzxq gzxq : gzxqList) {
                titleList.add(gzxq.getFgzxmc());
                dataList.add(gzxq.getFgzxz());
            }

            // 文件名称
            String title = gzjl.getFxm()+"-"+gzjl.getFnf()+"-"+gzjl.getFyf();

            String rootUrl = localFileUploadUtils.getTempFileRootUrl();

            List<List<String>> resultList = new ArrayList<>();
            resultList.add(titleList);
            resultList.add(dataList);

            File outFile = ExcelUtils.getLocalDempXlsExcel(resultList, title, rootUrl);

            localFileUploadUtils.ejzLocalFileByZdyFile(outFile,response);
        }
    }

    /**
     * 分页查询-工资记录详情统计
     * @param gzjl
     * @param gzxs 工资项
     * @param startYear 开始年份 (2020-2023)
     * @param endYear 结束年份 (2020-2023)
     * @param startMonth 开始月份 (1-12)
     * @param endMonth 结束月份 (1-12)
     */
    public HttpResult findGzjlxqPage(Page<SpcyGzjlDto> page,SpcyOaGzjl gzjl,String gzxs,
                               String startYear,String endYear,
                               String startMonth,String endMonth){
        if (StringUtils.isBlank(startYear) && StringUtils.isBlank(endYear)){
            String nowYear = DateConversionUtils.DateToYear(new Date());
            startYear = nowYear;
            endYear = nowYear;
        }
        if (StringUtils.isBlank(startMonth) && StringUtils.isBlank(endMonth)){
            String nowMonth = DateConversionUtils.DateToIntegerMonth(new Date());
            nowMonth = DateConversionUtils.DateToMonthString(nowMonth);
            endMonth = nowMonth;
        }
        if (StringUtils.isNotBlank(startMonth)){
            startMonth += "月";
        }
        if (StringUtils.isNotBlank(endMonth)){
            endMonth += "月";
        }
        IPage<SpcyGzjlDto> pageList = spcyOaGzjlMapper.findGzjlxqPage(page, gzjl, gzxs, startYear, endYear, startMonth, endMonth);
        return HttpResult.ok(pageList);
    }

    /**
     * 获取工资记录详情统计-工资项合计
     */
    public String getGzjlxqHj(SpcyOaGzjl gzjl,String gzxs,
                              String startYear,String endYear,
                              String startMonth,String endMonth){
//        String total = "0";
        List<String> hjList = spcyOaGzjlMapper.getGzjlxqHj(gzjl, gzxs, startYear, endYear, startMonth, endMonth);

        /*if (StringUtils.isNotBlank(hj)) {
            total = hj;
        }*/
        BigDecimal total = new BigDecimal("0");
        for (String hj : hjList){
            if (!StringPatternUtils.checkStringContainChinese(hj)){
                BigDecimal js = new BigDecimal(hj);
                total = total.add(js);
            }
        }

        return total.toString();
    }
    /**---------------------------------------------(废弃)----------------------------------------------------------*/

    /**
     * 导出工资统计功能excel文件  （废弃）
     * @param gzjl
     * @param gzxs 工资项
     * @param startYear 开始年份 (2020-2023)
     * @param endYear 结束年份 (2020-2023)
     * @param startMonth 开始月份 (1-12)
     * @param endMonth 结束月份 (1-12)
     */
    public void downloadGzjlStat(SpcyOaGzjl gzjl,String gzxs,
                                 String startYear,String endYear,
                                 String startMonth,String endMonth,HttpServletResponse response){
        List<List<String>> resultList = new ArrayList<>();

        if (StringUtils.isNotBlank(startMonth)){
            startMonth += "月";
        }
        if (StringUtils.isNotBlank(endMonth)){
            endMonth += "月";
        }

        int jbNumber = 5; // 基本长度
        String[] titles = new String[]{"序号","用工性质","姓名","年份","月份"};
        List<String> titleList = CollectionUtil.newArrayList(titles);

        List<String> totalList = new ArrayList<>(); // 合计数据

        // 标题构建
        List<String> gzxList = StringPatternUtils.getListByIds(gzxs);
        for (int i = 0; i < gzxList.size(); i++){
            String gzx = gzxList.get(i);
            titleList.add(gzx);

            BigDecimal totalBig = new BigDecimal("0"); // 合计
            List<SpcyOaGzxq> valueList = spcyOaGzxqService.list(new LambdaQueryWrapper<SpcyOaGzxq>()
                    .eq(SpcyOaGzxq::getFgzxmc, gzx)
                    .orderByAsc(SpcyOaGzxq::getFgzxxh));
            for (int v=0; v<valueList.size(); v++){
                if (StringUtils.isBlank(valueList.get(v).getFgzxz())){
                    continue;
                }
                BigDecimal valBig = new BigDecimal(valueList.get(v).getFgzxz());
                totalBig = totalBig.add(valBig);
            }
            totalList.add(totalBig.toString());
        }
        resultList.add(titleList);

        // 查询工资记录
        List<SpcyOaGzjl> gzjlList = spcyOaGzjlMapper.getGzjlList(gzjl, gzxs, startYear, endYear, startMonth, endMonth);

        for (int jl=0; jl<gzjlList.size(); jl++){
            List<String> dataList = new ArrayList<>();
            SpcyOaGzjl nr = gzjlList.get(jl);
            dataList.add(String.valueOf(jl+1));
            dataList.add(nr.getFgztclx());
            dataList.add(nr.getFxm());
            dataList.add(nr.getFnf());
            dataList.add(nr.getFyf());

            // 相关人员的工资项
            List<SpcyGzjlDto> gzjlList2 = spcyOaGzjlMapper.getGzjlDtoList(nr.getFxm(),gzxs);

            for (int i = 0; i < gzxList.size(); i++){
                String gzxNr = "";

                for (int j=0; j<gzjlList2.size(); j++){
                    if (gzxList.get(i).equals(gzjlList2.get(j).getFgzxmc())){
                        gzxNr = gzjlList2.get(j).getFgzxz();
                    }

                }
                dataList.add(gzxNr);
            }
            resultList.add(dataList);
        }

        // 合计
        if (StringUtils.isNotBlank(gzxs)) {
            List<String> hjList = new ArrayList<>();
            for (int i=0; i<titleList.size(); i++) {
                if (i == 0){
                    hjList.add("合 计");
                    continue;
                }

                if (i>jbNumber-1){
                    hjList.add(totalList.get(i-jbNumber));
                }else {
                    hjList.add("");
                }
            }
            resultList.add(hjList);
        }

        // 文件名称
        String title = "工资统计"+"("+DateConversionUtils.DateToYear(new Date())+")";

        String rootUrl = localFileUploadUtils.getTempFileRootUrl();

        File outFile = ExcelUtils.getLocalDempXlsExcel(resultList, title, rootUrl);

        localFileUploadUtils.ejzLocalFileByZdyFile(outFile,response);
    }


}
